#include <stdlib.h>
#include <stdio.h>

#include "figStack.h"
#include "util.h"

#line 6 "figStack.c"


void initstack ( FigStack * Figures, int length ) {

    Figures->figProperties = malloc(sizeof(struct Properties)*length);

    if ( !Figures->figProperties ) {
        fprintf(stderr, "draw2 %d: error\n", __LINE__);
        exit(EXIT_FAILURE);
    }

    Figures->figureCount = 0;
    Figures->currSize = length;
}

void addFig ( FigStack * Figures, char * localFigName ) {

    if ( Figures->figureCount == Figures->currSize )
        extendFigStack(Figures);

    initfig(Figures, localFigName);
}

/* initfig() takes a string figName and copies it into
 * Figures[figIndex].figureName.  It sets its drawCount to 0
 * and sets isdefined to 1. */
void initfig ( FigStack * Figures, char * figName ) {

    int figIndex = Figures->figureCount;
    strncpy(Figures->figProperties[figIndex].figureName, figName, MAXLEN_FIG+1);

    Figures->figProperties[figIndex].dx = malloc(sizeof(double));
    Figures->figProperties[figIndex].dy = malloc(sizeof(double));

    Figures->figProperties[figIndex].drawCount = 0;
    Figures->figProperties[figIndex].isdefined = 1;
}

/* updatefig() updates information in Figures at index position with
 * parameters found in string.  Integer type represents different types
 * of parameters. */
void updatefig ( char * string, FigStack * Figures, int position, int type ) {

    int drawCount;
    double * doublesPair;


    /* Get parameters and store them accordingly. */
    if ( type == 2 ) {  /* FigStack definitions. */
        doublesPair = getDoubles(string, type, 2);
        if ( doublesPair == NULL ) {
            fprintf(stderr, "draw2 %d: error\n", __LINE__);
            exit(EXIT_FAILURE);
        }
        Figures->figProperties[position].x = *doublesPair;
        Figures->figProperties[position].y = *(doublesPair+1);
    }
    else if ( type == 1 ) {     /* Draw commands. */
        doublesPair = getDoubles(string, type, 2);
        if ( doublesPair == NULL ) {
            fprintf(stderr, "draw2 %d: error\n", __LINE__);
            exit(EXIT_FAILURE);
        }
        drawCount = Figures->figProperties[position].drawCount;
        Figures->figProperties[position].dx[drawCount] = *doublesPair;
        Figures->figProperties[position].dy[drawCount] = *(doublesPair+1);
        Figures->figProperties[position].drawCount++;

        plusOneDraw(Figures, position);
    }

    free(doublesPair);
}

void plusOneDraw(FigStack * Figures, int position) {

    Figures->figProperties[position].dx = realloc( Figures->figProperties[position].dx,
                                                   sizeof(double)*
                                                   (Figures->figProperties[position].drawCount + 1));

    Figures->figProperties[position].dy = realloc( Figures->figProperties[position].dy,
                                                   sizeof(double)*
                                                   (Figures->figProperties[position].drawCount + 1));
    if ( !(Figures->figProperties[position].dx) ||
         !(Figures->figProperties[position].dy) ) {
        fprintf(stderr, "draw2 %d: error\n", __LINE__);
        exit(EXIT_FAILURE);
    }
}

/* getFigIndex() retrieves the index associated with nameString
 * inside Figures, and returns it.  Otherwise -1 is returned. */
int getFigIndex ( char * nameString, FigStack * Figures ) {

    int i;
    for ( i = 0; i < Figures->figureCount; i++ ) {
        if ( strncmp(nameString,
                    Figures->figProperties[i].figureName, MAXLEN_FIG+1) == 0 ) {
            return i;
        }
    }

    return -1;
}

/* exists() looks for nameString inside Figures.
 * It returns 1 if nameString was found, or 0 otherwise. */
int figexists ( char * nameString, FigStack * Figures ) {

    int i;
    for ( i = 0; i < Figures->figureCount; i++ ) {

        if ( !(Figures->figProperties[i].isdefined) )
            continue;

        if (strncmp(nameString,
                    Figures->figProperties[i].figureName, MAXLEN_FIG+1) == 0 )
            return 1;

    }

    return 0;
}

/* clearfig() takes a position index in Figures and resets its deltas
 * array to reset. */
void clearfig ( FigStack * Figures, int position, double resetvalue ) {

    int drawCount = Figures->figProperties[position].drawCount;

    memset(Figures->figProperties[position].dx,
            resetvalue, sizeof(double)*drawCount);

    memset(Figures->figProperties[position].dy,
            resetvalue, sizeof(double)*drawCount);

    Figures->figProperties[position].drawCount = 0;
}

void extendFigStack ( FigStack * Figures  ) {

    Figures->figProperties = realloc(Figures->figProperties, sizeof(struct Properties) *
                                     Figures->currSize * 2 );

    if ( !(Figures->figProperties) ) {
        fprintf(stderr, "draw %d: error\n", __LINE__);
        exit(EXIT_FAILURE);
    }

    Figures->currSize *= 2;
}



